package com.neusoft.bizcore.activiti.service.impl;

import java.util.List;

import javax.persistence.EntityNotFoundException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.neusoft.bizcore.activiti.converter.ProcessFormConverter;
import com.neusoft.bizcore.activiti.dto.ProcessFormDTO;
import com.neusoft.bizcore.activiti.model.ProcessForm;
import com.neusoft.bizcore.activiti.repository.ProcessFormRepository;
import com.neusoft.bizcore.activiti.service.ProcessFormItemService;
import com.neusoft.bizcore.activiti.service.ProcessFormService;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;

@Service
@Transactional
public class ProcessFormServiceImpl implements ProcessFormService {

    @Autowired
    private ProcessFormRepository processFormRepository;
    @Autowired
    private ProcessFormConverter processFormConverter;
    @Autowired
    private ProcessFormItemService processFormItemService;

    @Override
    public List<ProcessFormDTO> index(final Searchable searchable) {
        final List<ProcessForm> models = this.processFormRepository.index(searchable);
        return this.processFormConverter.toListDTO(models);
    }

    @Override
    public Page<ProcessFormDTO> search(final Pageable pageable, final Searchable searchable) {
        final Page<ProcessForm> result = this.processFormRepository.search(pageable, searchable);
        return this.processFormConverter.toPageDTO(result);
    }

    @Override
    public ProcessFormDTO create(final ProcessFormDTO dto) {

        final ProcessForm check = this.processFormRepository.findByCode(dto.getCode());

        if (check != null) {
            throw new UnitedException("表单编码不能重复");
        }

        final ProcessForm model = this.processFormConverter.toModel(dto);

        this.processFormRepository.save(model);
        final ProcessFormDTO result = this.processFormConverter.toDTO(model);

        dto.getItems().stream().map(m -> {
            m.setFormCode(model.getCode());
            return this.processFormItemService.create(m);
        }).forEach(result.getItems()::add);

        return result;
    }

    @Override
    public ProcessFormDTO update(final Long id, final ProcessFormDTO dto) {

        ProcessForm model;

        final ProcessForm check = this.processFormRepository.findByCode(dto.getCode());

        if ((check != null) && (id != check.getId())) {
            throw new UnitedException("表单编码不能重复");
        }

        try {
            model = this.processFormRepository.getOne(id);
            model.getItems().clear();
            this.processFormItemService.deleteByFormCode(model.getCode());
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        dto.setId(model.getId());
        model = this.processFormConverter.toModel(dto);
        this.processFormRepository.save(model);

        final ProcessFormDTO result = this.processFormConverter.toDTO(model);

        dto.getItems().stream().map(m -> {
            m.setFormCode(dto.getCode());
            m.setId(null);
            return this.processFormItemService.create(m);
        }).forEach(result.getItems()::add);

        return result;
    }

    @Override
    public ProcessFormDTO details(final Long id) {

        ProcessForm model;
        try {
            model = this.processFormRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        return this.processFormConverter.toDTO(model);
    }

    @Override
    public void delete(final Long id) {

        this.processFormRepository.deleteById(id);

    }

    @Override
    public String getFormNameBykey(final String key) {
        String result = "";
        if (StringUtils.isNotEmpty(key)) {
            final ProcessForm form = this.processFormRepository.findByCode(key);
            if (null != form) {
                result = form.getName();
            }
        }

        return result;
    }

}
